home *** CD-ROM | disk | FTP | other *** search
- /* Routines for AX.25 encapsulation in KISS TNC
- * Copyright 1991 Phil Karn, KA9Q
- */
- #include "global.h"
- #include "config.h"
- #include "mbuf.h"
- #include "iface.h"
- #include "kiss.h"
- #include "slip.h"
- #include "asy.h"
- #include "ax25.h"
- #ifdef CRCSET
- #include "crc.h"
- #endif
-
- /* Process incoming KISS TNC frame */
- void
- kiss_recv(struct iface *iface,struct mbuf *bp)
- {
-
- #ifdef CRCSET
- char kisstype;
- if(bp &&(*bp->data & 0x80)){
- if(check_crc(bp)){
- iface->crcerrors++;
- free_p(bp);
- return;
- }
- }
- kisstype = PULLCHAR(&bp);
- switch(kisstype & 0xf){
- case KISS_DATA:
- ax_recv(iface,bp);
- break;
- default:
- free_p(bp);
- break;
- }
- }
- #endif
-
- #ifndef CRCSET
- struct iface *kissif;
-
- char kisstype = PULLCHAR(&bp);
- int port = kisstype >> 4;
-
- if((kissif = Slip[iface->xdev].kiss[port]) == NULLIF) {
- free_p(bp);
- return;
- }
-
- switch(kisstype & 0xf){
- case KISS_DATA:
- ax_recv(kissif,bp);
- break;
- default:
- free_p(bp);
- break;
- }
- }
- #endif
-
- #if defined (KISS) && (defined(ASY) || defined(SCC))
- /* Send raw data packet on KISS TNC */
- int
- kiss_raw(struct iface *iface,struct mbuf *data)
- {
- register struct mbuf *bp;
-
- /* Put type field for KISS TNC on front */
- if((bp = pushdown(data,1)) == NULLBUF){
- free_p(data);
- return -1;
- }
- bp->data[0] = KISS_DATA;
- #ifndef CRCSET
- bp->data[0] |= (iface->port << 4);
- if(iface->port){
- iface->rawsndcnt++;
- iface->lastsent = secclock();
- }
- slip_raw(Slip[iface->xdev].iface,bp);
- return 0;
-
- #endif
- #ifdef CRCSET
- if (iface->sendcrc){
- (bp->data[0]|= 0x80);
- append_crc(bp);
- }
- slip_raw(iface,bp);
- return 0;
-
-
- #endif
- }
-
-
- /* Perform device control on KISS TNC by sending control messages */
- int
- kiss_ioctl(struct iface *iface,int argc,char *argv[])
- {
- struct mbuf *hbp;
- int i;
- char *cp;
-
- if(argc < 1){
- tputs("Data field missing\n");
- return -1;
- }
- /* Allocate space for arg bytes */
- hbp = ambufw((int16)argc);
- hbp->cnt = argc;
- hbp->next = NULLBUF;
- for(i = 0, cp = hbp->data; i < argc; )
- *cp++ = atoi(argv[i++]);
-
- if(hbp->data[0] != (char) KISS_RETURN)
- hbp->data[0] |= (iface->port << 4);
-
- if(iface->port){
- iface->rawsndcnt++;
- iface->lastsent = secclock();
- }
- slip_raw(Slip[iface->xdev].iface,hbp); /* Even more "raw" than kiss_raw */
- return 0;
- }
-
- static int
- kiss_stop(register struct iface *iface,int tmp)
- {
- Slip[iface->xdev].kiss[iface->port] = NULLIF;
- return 0;
- }
-
- /* Attach a kiss interface to an existing asy interface in the system
- * argv[0]: hardware type, must be "kiss"
- * argv[1]: master interface, e.g., "ax4"
- * argv[2]: kiss port, e.g., "4"
- * argv[3]: interface label, e.g., "ax0"
- * argv[4]: maximum transmission unit, bytes
- */
- int
- kiss_attach(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct iface *if_asy, *if_kiss;
- int port;
- char portmsg[] = "Port %d already allocated on iface %s\n";
-
- if((if_asy = if_lookup(argv[1])) == NULLIF){
- tprintf(Badif,argv[1]);
- return -1;
- }
- if(if_lookup(argv[3]) != NULLIF){
- tprintf(Ifexist,argv[4]);
- return -1;
- }
- if((port = atoi(argv[2])) < 1){
- tprintf(portmsg,0,argv[1]);
- return -1;
- }
-
- if(port > 15)
- port = 15;
-
- if(Slip[if_asy->xdev].kiss[port] != NULLIF){
- tprintf(portmsg,port,argv[1]);
- return -1;
- }
- /* Create interface structure and fill in details */
- if_kiss = (struct iface *)mxallocw(sizeof(struct iface));
- if_kiss->addr = if_asy->addr;
- if_kiss->name = strxdup(argv[3]);
-
- if_kiss->mtu = (argc >= 5) ? atoi(argv[4]) : if_asy->mtu;
-
- if_kiss->dev = if_asy->dev;
- if_kiss->stop = kiss_stop;
- setencap(if_kiss,"AX25");
- if_kiss->ioctl = kiss_ioctl;
- if_kiss->raw = kiss_raw;
- if_kiss->hwaddr = strxdup(Mycall);
- if_kiss->xdev = if_asy->xdev;
- init_maxheard(if_kiss);
- init_flags(if_kiss);
- if_kiss->next = Ifaces;
- if_kiss->niface = Niface++;
- if_kiss->port = port;
- Ifaces = if_kiss;
- Slip[if_kiss->xdev].kiss[if_kiss->port] = if_kiss;
- return 0;
- }
-
- #endif /* ax25 + asy | scc */